#ifndef _BUOLA_CV_IO_CKINECTDEVICE_OPENNI_H_
#define _BUOLA_CV_IO_CKINECTDEVICE_OPENNI_H_

#include <buola/buola.h>
#include <buola/threads/thread.h>
#include <buola/threads/condition_variable.h>
#include <buola/utility/usignal.h>
#include <buola/image/point.h>

#include <atomic>
#include <libfreenect/libfreenect.h>

namespace buola { namespace cvi {

class CKinectDevice
{
public:
    CKinectDevice(freenect_context *pContext,int pDeviceNum);
    ~CKinectDevice();
    
    void Start();
    void Stop();
    
    std::pair<img::CImage_rgb8,img::CImage_gray32f> GetOne();

    USignal<void(const img::CImage_rgb8&,const img::CImage_gray32f&)> sImages;
    
private:
    void Initialize();

    void OnThread();
    
    void DoStart();
    void DoStop();
    void DoIteration(int pCount);
    
private:
    freenect_context *mContext;
    freenect_device *mDevice;
    int mDeviceNum;
    
    std::atomic<bool> mInitialized;
/*
    ///focal length for IR camera producing depth information in native SXGA mode
    float mDepthFocalLengthSXGA;
    ///distance between the projector and the IR camera
    float mBaseline;
    ///focal length for regular camera producing color images in native SXGA mode
    float mRGBFocalLengthSXGA;

    ///the value for shadow (occluded pixels)
    XnUInt64 mShadowValue;
    ///the value for pixels without a valid disparity measurement
    XnUInt64 mNoSampleValue;
*/
    thread mThread;
    mutex mMutex;
    condition_variable mCondVar;

    int mSyncIndex;
    mutex mSyncMutex;
    condition_variable mSyncCondVar;
    img::CImage_rgb8 mRGBBack;
    img::CImage_rgb8 mSyncImageRGB;
    img::CImage_gray32f mSyncImageDepth;
    
    std::atomic<int> mStartCount;    
    
    bool mStarted;
};

/*namespace cvi*/ } /*namespace buola*/ }

#endif
